home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Primitives.c
-
- Contains: QuickDraw GX to PostScript conversion code.
- File contains Routines for the Geometric Primitives.
- Bitmaps and text will be in their own files
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1991-1997 by Apple Computer, Inc., all rights reserved.
- */
-
- #include <GXGraphics.h>
- #include "GXToPSBuildConfig.h"
- #include "GXToPostScript.h"
- #include "IOUtilities.h"
- #include "RDUtil.h"
- #include "FontHandler.h"
- #include "PublicPostScriptIE.h"
- #include "private.h"
- #include "PSIEResources.h"
- #include "GXErrors.h"
-
-
- #ifdef resumeLabel
- #undef resumeLabel
- #endif
- #define resumeLabel(exception)
-
- /***************************************
-
- DoExec:
- Routine outputs the PostScript operator "exec"
-
- ****************************************/
- OSErr DoExec(TIEGlobalsHdl hGlobals);
- OSErr DoExec(TIEGlobalsHdl hGlobals)
- {
- OSErr status;
- unsigned char execString[] = "exec\n";
-
- status = PSIEBufferData(hGlobals, execString, 5, gxNoBufferOptions);
- ncheck(status);
-
- return(status);
-
- }//DoExec
-
-
- /****************************************
-
- DoLineto:
- Routine outputs a lineto for the specified point
-
- rdParams: The RD parameter block.
- thePoint: The point to draw the line to.
-
- ******************************************/
- OSErr DoLineto(TRDParams *rdParams, gxPoint *thePoint);
- OSErr DoLineto(TRDParams *rdParams, gxPoint *thePoint)
- {
- OSErr status;
-
- rdParams->resIndex = kLineto;
- status = RDResPrintf(rdParams, thePoint);
- ncheck(status);
- return(status);
-
- }//DoLineto
-
- /******************************************
-
- DoClosepath:
- Routine outputs a closepath.
-
- rdParams: The RD parameter block.
-
- *******************************************/
- OSErr DoClosepath(TRDParams *rdParams);
- OSErr DoClosepath(TRDParams *rdParams)
- {
- OSErr status;
-
- rdParams->resIndex = kClosepath;
- status = RDResPrintf(rdParams);
- ncheck(status);
- return(status);
-
- }//DoClosepath
-
-
-
- /*******************************************
-
- DoCurveto:
- Routine converts a quadratic to a cubic
- and does a curveto.
-
- rdParams: The RD Parameter block.
- q: The array of quadratic points.
-
- *********************************************/
- OSErr DoCurveto(TRDParams *rdParams, gxPoint q[3]);
- OSErr DoCurveto(TRDParams *rdParams, gxPoint q[3])
- {
- OSErr status;
- gxPoint c1, c2, c3; // cubic control points.
-
- c1.x = q[0].x + FixedDivide( (q[1].x - q[0].x) << 1, ff(3) );
- c2.x = q[2].x - FixedDivide( (q[2].x - q[1].x) << 1, ff(3) );
-
- c1.y = q[0].y + FixedDivide( (q[1].y - q[0].y) << 1, ff(3) );
- c2.y = q[2].y - FixedDivide( (q[2].y - q[1].y) << 1, ff(3) );
-
- c3 = q[2];
-
-
- rdParams->resIndex = kCurveto;
- // Convert them to positions relative to q0.
-
- status = RDResPrintf(rdParams, &c1, &c2, &c3);
-
- ncheck(status);
- return(status);
-
- }//DoCurveto
-
- //<FF>
- /***********************************
- FullShapePrimitive:
-
- Output a path for a full shape in PostScript.
-
- ************************************/
- OSErr _FullShapePrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- #pragma unused(theShape, geomOptions)
- OSErr status;
- TRDParams* pRDParams;
- gxShapeFill theFill = GXGetShapeFill(theShape);
-
- pRDParams = (*hIEGlobals)->pRDParams;
- pRDParams->resIndex = kFullPath;
-
- status = RDResPrintf(pRDParams);
- ncheck(status);
-
- return(status);
-
- }//FullShapePrimitive
-
-
- /***********************************
- EmptyShapePrimitive:
-
- Output a path for a full shape in PostScript.
-
- ************************************/
- OSErr _EmptyShapePrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- #pragma unused(theShape)
- OSErr status;
- TRDParams* pRDParams;
-
- /** For clipping, output a geometry, for drawing do nothing **/
-
- if (geomOptions & eClipGeometry) {
-
- pRDParams = (*hIEGlobals)->pRDParams;
- pRDParams->resIndex = kEmptyPath;
-
- status = RDResPrintf(pRDParams);
- ncheck(status);
-
- } else {
-
- status = noErr;
-
- }//end if
-
- return(status);
-
- }//FullShapePrimitive
-
- //<FF>
- /***********************************
- RectanglePrimitive:
-
- Convert a rectangle into PostScript
- All that really happens is that the 4
- parameters (top left width height) are left
- on the PS operand stack. The caller is
- then responsible for dealing with it.
- This allows the use of faster level-2
- rectangle procedures when possible.
-
- *************************************/
- OSErr _RectanglePrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- #pragma unused(geomOptions)
- OSErr status;
- gxRectangle theRect;
- gxPoint topLeft;
- TRDParams* pRDParams;
- long value;
- Boolean causesOverflow = false;
-
- pRDParams = (*hIEGlobals)->pRDParams;
-
- GXGetRectangle(theShape, &theRect);
- topLeft.x = theRect.left;
- topLeft.y = theRect.top;
-
- /*** Check to see if width or height will cause overflow ***/
-
- value = (long)(theRect.right >> 16) - (long)(theRect.left >> 16);
- if ( (value < -32768) || (value > 32767)) {
-
- causesOverflow = true;
-
- } else {
-
- value = (long)(theRect.right >> 16) - (long)(theRect.left >> 16);
- if ( (value < -32768) || (value > 32767) )
- causesOverflow = true;
-
- }//end if
-
- /** Now output the parameters for the rectange operators **/
-
- if (!causesOverflow) {
-
- /** As long as there is no overflow, compute width and height here **/
- gxPoint widthHeight;
-
- widthHeight.x = theRect.right - theRect.left;
- widthHeight.y = theRect.bottom - theRect.top;
-
- pRDParams->resIndex = kRectPoints;
- status = RDResPrintf(pRDParams, &topLeft, &widthHeight);
- nrequire(status, failed_Output);
-
- } else {
-
- /*** relative rectangle values cause overflow, use absolute and do subtraction on printer ***/
-
- pRDParams->resIndex = kRectPointsAbs;
- status = RDResPrintf(pRDParams, &topLeft, theRect.right, theRect.left, theRect.bottom, theRect.top);
- nrequire(status, failed_Output);
-
- }//end if
-
-
- /** If we are making a procedure make the rectangle the path **/
- /*** We really should check to see if we can do rectfill, etc…
- However, this requires fixing QD2Fill to check stack for true/false
- *****/
- if (geomOptions & eMakeProcedure) {
-
- pRDParams->resIndex = kRectPath;
- status = RDResPrintf(pRDParams);
- nrequire(status, failed_Output);
-
- }//end if
-
- failed_Output:
- return(status);
-
- }//RectanglePrimitive
-
-
- //<FF>
- /***********************************
- LinePrimitive:
-
- Convert a line into PostScript
-
- *************************************/
- OSErr _LinePrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- #pragma unused(geomOptions)
- OSErr status;
- TRDParams* pRDParams;
- gxLine theLine;
-
-
- GXGetLine(theShape, &theLine);
-
- pRDParams = (*hIEGlobals)->pRDParams;
-
- status = DoMoveto(pRDParams, &theLine.first);
- nrequire(status, failed_Output);
-
- status = DoLineto(pRDParams, &theLine.last);
- ncheck(status);
-
- failed_Output:
-
- return(status);
-
- }//LinePrimitive
-
- //<FF>
- /***********************************
- CurvePrimitive:
-
- Convert a curve into PostScript
-
- *************************************/
- OSErr _CurvePrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- #pragma unused(geomOptions)
- OSErr status;
- TRDParams* pRDParams;
- gxCurve theCurve;
-
- GXGetCurve(theShape, &theCurve);
-
- pRDParams = (*hIEGlobals)->pRDParams;
-
- status = DoMoveto(pRDParams, &theCurve.first);
- nrequire(status, failed_Output);
-
- /** note, DoCurveto takes array of points, the curve struct parallels this.**/
-
- status = DoCurveto(pRDParams, (gxPoint*)&theCurve);
- ncheck(status);
-
- failed_Output:
-
- return(status);
-
- }//CurvePrimitive
-
- //<FF>
- /***********************************
- PointPrimitive:
-
- Convert a point into PostScript
-
- *************************************/
- OSErr _PointPrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- #pragma unused(geomOptions)
- OSErr status;
- TRDParams* pRDParams;
- gxPoint thePoint;
-
-
- GXGetPoint(theShape, &thePoint);
-
- pRDParams = (*hIEGlobals)->pRDParams;
- pRDParams->resIndex = kPointPath;
-
- status = RDResPrintf(pRDParams, &thePoint);
- ncheck(status);
-
- return(status);
-
- }//PointPrimitive
-
-
- //<FF>
- /***********************************
- PolygonsPrimitive:
-
- Convert a multi-contoured polygon into PostScript
-
- *************************************/
- OSErr _PolygonsPrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- OSErr status = noErr;
- TRDParams* pRDParams;
- Ptr inPolygon; // We must walk through the polygons structure
- gxShapeAttribute theAttributes;
- long i, j;
- Boolean closeIt; // Is it open or closed.
- long nContours; // Number of contours.
- long nPoints; // Number of points in contour.
- gxPoint* pPoint; // Point to a point.
- long size;
- short stackLimit; // Usable stack limit for glyph shapes.
- short stackUsed; // How much stack have we used so far?
- Boolean wontFitOnStack;
- Boolean procOpen;
-
- /******
- Usable stack space for polygons:
-
- take real stack limit and subtract 25 to allow other parameters
- on stack involved in defining procedures, etc…
- *******/
- if (geomOptions & eMakeProcedure) { // we don't care otherwise.
-
- stackLimit = ( (*hIEGlobals)->params.opStackLimit ) - 50;
- ncheck((stackLimit < 0));
-
- wontFitOnStack = (GXCountShapePoints(theShape, 0) > (stackLimit / 3)); // 3 things on stack per point.
-
- } else {
-
- wontFitOnStack = false;
-
- }//end if
-
- /* If it is closedFrameFill we must close each contour */
- closeIt = (GXGetShapeFill(theShape) == gxClosedFrameFill);
-
- /***********
- Make sure we have access to the shape data structure,
- and then get it
- ***********/
- theAttributes = GXGetShapeAttributes(theShape);
- GXSetShapeAttributes(theShape, theAttributes | gxDirectShape);
- GXLockShape(theShape);
-
- status = GXGetGraphicsError(nil);
- nrequire(status, failed_KeepDirect);
-
-
- inPolygon = (Ptr)GXGetShapeStructure(theShape, &size); //Get a pointer to the structure.
- check(inPolygon);
-
- nContours = ((gxPolygons*)inPolygon)->contours; //Get the number of countours.
-
- inPolygon += sizeof(long); //Move pointer past contours field.
-
- stackUsed = 0;
-
- /** Now output all of the contours, break up to fit on stack if necessary **/
-
- if (wontFitOnStack) {
-
- nrequire(status = DoBeginProcedure(hIEGlobals), failed_Output);
- procOpen = true;
-
- }//end if
-
- pRDParams = (*hIEGlobals)->pRDParams;
-
- for (i = 0; i < nContours; i++) { // Output the contours.
-
- nPoints = *(long*)inPolygon; // Get the number of points for this contour.
-
- inPolygon += sizeof(long); // Move to the data.
-
- if (nPoints > 0) {
-
- pPoint = (gxPoint*)inPolygon; // Get the first point in contour.
- inPolygon += sizeof(gxPoint); // Move past it.
-
- status = DoMoveto(pRDParams, pPoint); // Do the moveto
- nrequire(status, failed_Output);
-
- stackUsed += 3; // Put a point on the stack and a moveto
-
- for (j = 1; j < nPoints; j++) { // Output the points for the countour.
-
- pPoint = (gxPoint*)inPolygon; // Get the next point.
- inPolygon += sizeof(gxPoint);
-
- status = DoLineto(pRDParams, pPoint); // Add a line to the PS path.
- nrequire(status, failed_Output);
-
- stackUsed += 3; // put a point on the stack plus a lineto
-
- if ((stackUsed > stackLimit) & wontFitOnStack) {
-
- nrequire(status = DoEndProcedure(hIEGlobals), failed_Output);
- nrequire(status = DoExec(hIEGlobals), failed_Output); // put an exec into on the stack
- nrequire(status = DoBeginProcedure(hIEGlobals), failed_Output); // Open a new procedure
-
- stackUsed = 0;
-
- }//end if
-
- }//end for j
-
- if (closeIt) {
-
- status = DoClosepath(pRDParams);
- nrequire(status, failed_Output);
-
- ++stackUsed; // put a closepath on the stack.
-
- }//end if
-
- }//end for
-
- }//endo for i
-
- if (procOpen & wontFitOnStack) { // left an open procedure
-
- nrequire(status = DoEndProcedure(hIEGlobals), failed_Output);
- nrequire(status = DoExec(hIEGlobals), failed_Output);
-
- }//end if
-
-
- failed_Output:
- /** Restore the shape to the way we got it. **/
-
- GXSetShapeAttributes(theShape, theAttributes);
- GXUnlockShape(theShape);
-
- failed_KeepDirect:
-
- return(status);
-
- }//PolygonsPrimitive
-
-
-
- //<FF>
- /***********************************
- PathsPrimitive:
-
- Convert a multi-contoured path into PostScript
-
- *************************************/
- OSErr _PathsPrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- OSErr status;
- TRDParams* pRDParams;
- Ptr inPath; // We must walk through the Paths structure
- gxShapeAttribute theAttributes;
- long i, pointIndex;
- long size;
- long firstIndex, lastIndex; // Index of first and last point ON curve.
- Boolean closeIt; // Is it open or closed.
- long nContours; // Number of contours.
- long nPoints; // Number of points in contour.
- gxPoint* pPoint; // Point to a point.
- gxPoint firstPoint; // First point in the contour.
- gxPoint lastPoint; // The last point we output.
- register unsigned long* controlBitLong; // Pointer to control bits.
- register unsigned long cBitMask; // Mask for reading control bits.
- unsigned long lastBitMask; // Mask for last point in contour.
- long cBitSize; // Number of longs for control bits.
- gxPoint q[3]; // Quadratic control points.
- short qIndex; // Indicates #points in curve segment so far.
- Boolean isOff; // On the curve or off the curve.
- Boolean firstIsOn, lastIsOn;
- short stackLimit; // Usable stack limit for glyph shapes.
- short stackUsed; // How much stack have we used so far?
- Boolean wontFitOnStack;
- Boolean procOpen;
-
-
- /******
- Usable stack space for paths:
-
- take real stack limit and subtract 50 to allow other parameters
- on stack involved in defining procedures, etc…
- *******/
- if (geomOptions & eMakeProcedure) { // we don't care otherwise.
-
- long numPoints;
-
- stackLimit = ( (*hIEGlobals)->params.opStackLimit ) - 50;
- ncheck((stackLimit < 0));
-
- status = PSCountShapePoints(theShape, 0, &numPoints);
- nrequire(status, failed_CountPoints);
-
- wontFitOnStack = (numPoints > (stackLimit / 3)); // 3 things on stack for each point.
-
- } else {
-
- wontFitOnStack = false;
-
- }//end if
-
-
- /* If it is closedFrameFill we must close each contour */
- closeIt = (GXGetShapeFill(theShape) == gxClosedFrameFill);
-
- /***********
- Make sure we have access to the shape data structure,
- and then get it
- ***********/
- theAttributes = GXGetShapeAttributes(theShape);
- GXSetShapeAttributes(theShape, theAttributes | gxDirectShape);
-
- GXLockShape(theShape);
-
- inPath = (Ptr)GXGetShapeStructure(theShape, &size); //Get a pointer to the structure.
- check(inPath);
-
- nContours = ((gxPaths*)inPath)->contours; //Get the number of countours.
- inPath += sizeof(long); //Move pointer past contours field.
-
- status = GXGetGraphicsError(nil);
- nrequire(status, failed_KeepDirect);
-
- stackUsed = 0;
-
- /** Now output all of the contours, break up to fit on stack if necessary **/
-
- if (wontFitOnStack) {
-
- nrequire(status = DoBeginProcedure(hIEGlobals), failed_Output);
- procOpen = true;
-
- }//end if
-
- pRDParams = (*hIEGlobals)->pRDParams;
-
- for (i = 0; i < nContours; i++) { // Output the contours.
-
- nPoints = *(long*)inPath; // Get the number of points for this contour.
- inPath += sizeof(long); // Move to the data.
-
- if (nPoints > 0) {
-
- controlBitLong = (unsigned long*)inPath; // Get to the control bits.
-
- cBitSize = (nPoints + 31) / 32; // Compute the size of control bits in longs.
-
- inPath += cBitSize * sizeof(long); // Skip past control bits, inPath now points to first point.
-
- pPoint = (gxPoint*)inPath; // Get the first point in contour, leave inPath pointing here.
-
- cBitMask = 0x80000000U; // Initilize the mask for reading bits.
-
- lastBitMask = 0x80000000U >> ((nPoints-1) & 0x0000001F); // Mod 32
-
-
- /** Compute the first and last point on the curve **/
-
- firstIsOn = ((*controlBitLong & cBitMask) == 0);
- lastIsOn = ( ( *(controlBitLong + cBitSize - 1) & lastBitMask) == 0);
-
- if (firstIsOn && lastIsOn) { // They both are on.
-
- firstPoint = *pPoint;
- firstIndex = 0;
- lastPoint = *(pPoint + nPoints - 1);
- lastIndex = nPoints;
- NEXTBIT(isOff, controlBitLong, cBitMask); // Read bit for 1st point, set up for next.
- ++pPoint;
-
- } else if (firstIsOn) { // first was on, last was off
-
- firstPoint = *pPoint;
- firstIndex = 0;
-
- lastPoint = firstPoint;
-
- lastIndex = nPoints + 1;
- NEXTBIT(isOff, controlBitLong, cBitMask); // Read bit for 1st point, set up for next.
- ++pPoint;
-
-
- } else if (lastIsOn) { // last was on, first is off
-
- register gxPoint* pLastPoint = pPoint + nPoints - 1;
-
- lastPoint = *pLastPoint;
- firstPoint = lastPoint;
- lastIndex = nPoints;
-
- firstIndex = -1;
-
- } else { // they were both off
-
- register gxPoint* pLastPoint = pPoint + nPoints - 1;
-
- firstIndex = -1;
- lastIndex = nPoints + 1;
-
- INTERPPOINT(lastPoint, *pPoint, *pLastPoint);
-
- firstPoint = lastPoint;
-
- } //end if
-
-
- /*** Output the contour ****/
-
- q[0] = firstPoint;
- qIndex = 0;
- status = DoMoveto(pRDParams, &(q[0]));
- nrequire(status, failed_Output);
-
- stackUsed += 3; // Put a point on the stack plus a moveto.
-
- // Loop over all points but the first and last ON the curve.
-
- NEXTBIT(isOff, controlBitLong, cBitMask); // Check the first point in the looping.
- pointIndex = firstIndex + 1;
- while (pointIndex < (lastIndex - 1)) { // I know, should cache lastPointIndex-1
-
- if (!isOff) { // If the next point is on the curve:
-
- if ( qIndex == 0) { // If we have only q0, then do a line and start over.
-
- status = DoLineto(pRDParams, pPoint);
- nrequire(status, failed_Output);
- q[0] = *pPoint++;
- ++pointIndex;
-
- NEXTBIT(isOff, controlBitLong, cBitMask);
-
- stackUsed += 3; // point for lineto plus the lineto
-
- } else { // We must have q0 and q1, do a curve: q0, q1, q2
-
- q[2] = *pPoint++;
- status = DoCurveto(pRDParams, q);
- nrequire(status, failed_Output);
- q[0] = q[2];
- qIndex = 0;
- ++pointIndex;
- NEXTBIT(isOff, controlBitLong, cBitMask);
-
- stackUsed += 7; // 3 points for curveto plus the curveto
-
- }//end if
-
- } else {
-
- if (qIndex == 0) { // If we only have one point so far, this becomes 2nd.
-
- q[1] = *pPoint++;
- qIndex = 1;
- NEXTBIT(isOff, controlBitLong, cBitMask);
- ++pointIndex;
-
- } else { // We had 2 points, interpolate to get 3rd and do a curve
-
- INTERPPOINT(q[2], q[1], *pPoint);
-
- status = DoCurveto(pRDParams, q);
- nrequire(status, failed_Output);
- qIndex = 0;
- q[0] = q[2];
-
- stackUsed += 7; // 3 points for curveto plus the curveto
-
- }//end if
-
- }//end if
-
- if ((stackUsed > stackLimit) & wontFitOnStack) {
-
- nrequire(status = DoEndProcedure(hIEGlobals), failed_Output);
- nrequire(status = DoExec(hIEGlobals), failed_Output); // put an exec into on the stack
- nrequire(status = DoBeginProcedure(hIEGlobals), failed_Output); // Open a new procedure
-
- stackUsed = 0;
-
- }//end if
-
- }//end while
-
-
- /** Now handle the last point that is ON the curve in the contour **/
-
- if (qIndex == 0) { // If we only had one point so far, Do a line.
-
- status = DoLineto(pRDParams, &lastPoint);
- nrequire(status, failed_Output);
-
- stackUsed += 3; // point for lineto plus the lineto
-
- } else { // Else, we must have had 2 points so far, Do a curve.
-
- q[2] = lastPoint;
- status = DoCurveto(pRDParams, q);
- nrequire(status, failed_Output);
-
- stackUsed += 7; // 3 points for curveto plus the curveto.
-
- }//end if
-
- if (closeIt) {
-
- status = DoClosepath(pRDParams);
- nrequire(status, failed_Output);
-
- stackUsed += 1; // put the closepath on the stack.
-
- }//end if
-
- /** Point into the next contour - inPath was pointing to first point in contour **/
-
- inPath += nPoints * sizeof(gxPoint);
-
- }//end if
-
- }//endo for i
-
- if (procOpen & wontFitOnStack) { // left an open procedure
-
- nrequire(status = DoEndProcedure(hIEGlobals), failed_Output);
- nrequire(status = DoExec(hIEGlobals), failed_Output);
-
- }//end if
-
- failed_Output:
- /** Restore things, though the shape is a copy and we really don't have to. **/
- GXSetShapeAttributes(theShape, theAttributes);
- GXUnlockShape(theShape);
-
- failed_KeepDirect:
-
- failed_CountPoints:
-
- return(status);
-
- }//PathsPrimitive
-
-
-
- //<FF>
- /***********************************************
-
- Routine: CubicPrimitive
-
- Routine converts cubic synonym data into PostScript.
-
- We do not need to support procedure generation stack management
- here since shapes that come from patterns, dashes, etc… can never have tags
- and therefore never have cubic data associated with them.
-
- ************************************************/
- OSErr _CubicPrimitive(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions geomOptions)
- {
- #pragma unused(geomOptions)
- OSErr status;
- gxTag cubicTag;
- Ptr cubicData;
- Ptr inCubic, endCubic;
- long dataSize;
- short instruction;
- TRDParams *rdParams;
- gxPoint thePoints[3];
-
- rdParams = (*hIEGlobals)->pRDParams;
-
- GXGetShapeTags(theShape, gxCubicSynonymTag, 1, 1, &cubicTag);
-
- GXLockTag(cubicTag);
- cubicData = (Ptr)GXGetTagStructure(cubicTag, &dataSize);
- nrequire_action(status = GXGetGraphicsError(nil), failed_GetTag, GXUnlockTag(cubicTag););
-
- inCubic = cubicData;
- endCubic = cubicData + dataSize;
-
- while(inCubic < endCubic) {
-
- instruction = (short)(*inCubic) & gxCubicInstructionMask;
- inCubic += sizeof(short);
-
- switch(instruction) {
-
- case gxMoveToFlag:
-
- nrequire(status = DoMoveto(rdParams, (gxPoint*)inCubic), failed_Output);
- inCubic += sizeof(gxPoint);
-
- break;
-
- case gxLineToFlag:
-
- nrequire(status = DoLineto(rdParams, (gxPoint*)inCubic), failed_Output);
- inCubic += sizeof(gxPoint);
-
- break;
-
- case gxCurveToFlag:
-
- thePoints[0].x = ((gxPoint*)inCubic)->x;
- thePoints[0].y = ((gxPoint*)inCubic)->y;
- inCubic += sizeof(gxPoint);
-
- thePoints[1].x = ((gxPoint*)inCubic)->x;
- thePoints[1].y = ((gxPoint*)inCubic)->y;
- inCubic += sizeof(gxPoint);
-
- thePoints[2].x = ((gxPoint*)inCubic)->x;
- thePoints[2].y = ((gxPoint*)inCubic)->y;
- inCubic += sizeof(gxPoint);
-
- rdParams->resIndex = kCurveto;
- status = RDResPrintf(rdParams, &(thePoints[0]), &(thePoints[1]), &(thePoints[2]));
-
- nrequire(status, failed_Output);
-
- break;
-
- case gxClosePathFlag:
- nrequire(status = DoClosepath(rdParams), failed_Output);
- break;
-
- }//end switch
-
- }//end while
-
- ncheck(status);
-
- failed_Output:
-
- GXUnlockTag(cubicTag);
-
- failed_GetTag:
-
- return(status);
-
- }//CubicPrimitive